﻿package plugins.mstandio.LoadSpacePlus{
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;	
	
	import gs.TweenLite;	
	import zephyr.BroadcastEvent;		
	import plugins.mstandio.LoadSpacePlus.elements.Element;	
		
	
	/**	 
	 * Class preproceses usual command "loadSpace" before sending it to PanoSalado
	 * It analizes structure of spaces and allows better control on space loading
	 * also it keeps track on allready visited spaces
	 * @author mstandio
	 */
	public class LoadSpacePlus extends Sprite{
				
		/**
		 * Aggregates Elements objects that store data about spaces
		 */
		private var elements:Object;
		
		/**
		 * Stores mode name, that determines, types of executed actions  
		 * its value should be one of: "smart", "forcePreviews", "forceSpaces", "passive"
		 */
		private var mode:String; 
		
		/**
		 * while loading space disables possibility of loading aonther space
		 */
		private var locked:Boolean;
		
		/**
		 * for how long loading new spaces will be disabled
		 */
		private var unlockDelay:Number;
				
		private var moduleLoader:Object;
		private var ModuleLoader:Class;	
		
		private var PanoSalado:Class;		
		private var layerByName:Dictionary;			
		private var panoSalado:Object;		
		
		private var BroadcastEvent:Class;		
		
		/**
		 * constructor
		 */
		public function LoadSpacePlus() {			
			addEventListener(Event.ADDED_TO_STAGE, stageReady, false, 0, true);			
		}		
		private function stageReady(e:Event):void {                                            
			removeEventListener(Event.ADDED_TO_STAGE, stageReady);				
			
			this.locked = false;
			
			BroadcastEvent = ApplicationDomain.currentDomain.getDefinition("zephyr.BroadcastEvent") as Class;
			ModuleLoader = ApplicationDomain.currentDomain.getDefinition("ModuleLoader") as Class;
            moduleLoader = ModuleLoader(parent); 			
			moduleLoader.addEventListener(BroadcastEvent.ALL_LAYERS_LOADED, layersReady, false, 0, true);
			moduleLoader.addEventListener(BroadcastEvent.SPACE_LOADED, this.spaceLoaded, false, 5, true);
			moduleLoader.addEventListener(BroadcastEvent.LOADSPACEPLUS, this.loadSpace, false, 0, true);												
						
			this.getSettings();								
		}				
		
		private function layersReady(e:Event):void {
			PanoSalado = ApplicationDomain.currentDomain.getDefinition("PanoSalado") as Class;			
			layerByName = Dictionary( moduleLoader["layerByName"] );			
			panoSalado = PanoSalado( layerByName["PanoSalado"] );					
		}
		
		/**
		 * reads setting from xml file, builds array of objects that reflect spaces structure
		 */
		private function getSettings():void{			
			var settings:XML = moduleLoader.xmlByName["LoadSpacePlus"];			
			this.mode = (settings.@mode != undefined) ?  settings.@mode : "smart";	// default value		
			this.unlockDelay = (settings.@lock != undefined) ?  Number(settings.@lock) : 1.5; // default value		
			
			var panoSaladoXml:XML = moduleLoader.xmlByName["PanoSalado"] as XML;						
			var spacesList:XMLList   = panoSaladoXml.spaces.space.( @id.search(/\.preview$/) == -1 ); 	
			var previewsList:XMLList = panoSaladoXml.spaces.space.( @id.search(/\.preview$/) != -1 );	
			
			this.elements = new Object();
			
			var gotPreview:Boolean = false;
			
			for each(var space:XML in spacesList) {												
				 for each (var preview:XML in previewsList) {
					if (String(preview.@id) ==  String(space.@id) + ".preview") {
						gotPreview = true;
						break;
					}
				 }		
				 
				 
				 this.elements[space.@id] = new Element(space.@id, gotPreview);				 
				 gotPreview = false;				 
			}													
		}
		
		/**
		 * marks loaded spaces as visited
		 * @param e BroadcastEvent containing name of loaded space
		 */
		private function spaceLoaded(e:zephyr.BroadcastEvent):void {
			if (this.elements[e.info.spaceLoaded]){								
				if(!Element(this.elements[e.info.spaceLoaded]).spaceVisited){
					Element(this.elements[e.info.spaceLoaded]).spaceVisited = true;																	
					
				}
			}				
		}		
		
		/**
		 * proceses space name and loads space according to settings 
		 * @param id BroadcastEvent containing name of space to be loaded 
		 */
		private function loadSpace(e:zephyr.BroadcastEvent):void {
			
			if(!this.locked && panoSalado!=null){				
				this.locked = true;
				// enables loading spaces after specified period of time this prevents multiple clicks
				TweenLite.delayedCall(this.unlockDelay, this.unlock);
			
				// getting rid of ".preview" suffix if present
				var id_processed:String = (String(e.info.space).search(/\.preview$/) == -1) ? 
											String(e.info.space) : 
											String(e.info.space).substring(0, String(e.info.space).lastIndexOf(".preview"));
			
				// go to preview of space if space was not visited, go to space directly otherwise
				if (this.mode.toLowerCase() == "smart") {					
					
					// if space wasn't visited yet					
					if (!Element(this.elements[id_processed]).spaceVisited) {
						// if space has preview
						if (Element(this.elements[id_processed]).hasPreview) {
							
							panoSalado.loadSpace(id_processed + ".preview");
						// if space doesn't have preview
						}else {
							
							panoSalado.loadSpace(id_processed);
						}
					// if space was visited	
					}else {
						
						panoSalado.loadSpace(id_processed); 
					}				
			
				// force going to space preview				
				}else if (this.mode == "forcePreviews") {
					
					// if space has preview
					if (Element(this.elements[id_processed]).hasPreview) {
						
						panoSalado.loadSpace(id_processed + ".preview");
					// if space doesn't have preview 	
					}else {
						
						panoSalado.loadSpace(id_processed);
					}						
			
				// force going directly to space				
				}else if (this.mode == "forceSpaces") {
					
					panoSalado.loadSpace(id_processed);							
				
				
				// force going directly to space				
				}else if (this.mode == "passive") {
					
					panoSalado.loadSpace(e.info.space);							
				}
			}
		}				
		
		private function unlock():void {
			this.locked = false;
		}		
	}	
}